Refactor command-line parsing
authorMatthew Barnes <mbarnes@redhat.com>
Fri, 14 Nov 2014 19:00:13 +0000 (14:00 -0500)
committerMatthew Barnes <mbarnes@redhat.com>
Tue, 25 Nov 2014 00:36:07 +0000 (19:36 -0500)
Refactor command-line parsing to better utilize GOptionContext.  This
eliminates most of the manual parsing and global options are now shown
in the help output.

Here's a sample:

    $ ostree admin --help
    Usage:
      ostree admin [OPTION...] --print-current-dir|COMMAND

    Builtin "admin" Commands:
      cleanup
      config-diff
      deploy
      init-fs
      instutil
      os-init
      status
      switch
      undeploy
      upgrade

    Help Options:
      -h, --help         Show help options

    Application Options:
      --sysroot=PATH     Create a new OSTree sysroot at PATH
      -v, --verbose      Print debug information during command processing
      --version          Print version information and exit

https://bugzilla.gnome.org/show_bug.cgi?id=740295

42 files changed:
src/ostree/main.c
src/ostree/ot-admin-builtin-cleanup.c
src/ostree/ot-admin-builtin-deploy.c
src/ostree/ot-admin-builtin-diff.c
src/ostree/ot-admin-builtin-init-fs.c
src/ostree/ot-admin-builtin-instutil.c
src/ostree/ot-admin-builtin-os-init.c
src/ostree/ot-admin-builtin-status.c
src/ostree/ot-admin-builtin-switch.c
src/ostree/ot-admin-builtin-undeploy.c
src/ostree/ot-admin-builtin-upgrade.c
src/ostree/ot-admin-builtins.h
src/ostree/ot-admin-instutil-builtin-grub2-generate.c
src/ostree/ot-admin-instutil-builtin-selinux-ensure-labeled.c
src/ostree/ot-admin-instutil-builtin-set-kargs.c
src/ostree/ot-admin-instutil-builtins.h
src/ostree/ot-builtin-admin.c
src/ostree/ot-builtin-cat.c
src/ostree/ot-builtin-checkout.c
src/ostree/ot-builtin-checksum.c
src/ostree/ot-builtin-commit.c
src/ostree/ot-builtin-config.c
src/ostree/ot-builtin-diff.c
src/ostree/ot-builtin-fsck.c
src/ostree/ot-builtin-init.c
src/ostree/ot-builtin-log.c
src/ostree/ot-builtin-ls.c
src/ostree/ot-builtin-prune.c
src/ostree/ot-builtin-pull-local.c
src/ostree/ot-builtin-pull.c
src/ostree/ot-builtin-refs.c
src/ostree/ot-builtin-remote.c
src/ostree/ot-builtin-reset.c
src/ostree/ot-builtin-rev-parse.c
src/ostree/ot-builtin-show.c
src/ostree/ot-builtin-static-delta.c
src/ostree/ot-builtin-summary.c
src/ostree/ot-builtin-trivial-httpd.c
src/ostree/ot-builtins-common.c
src/ostree/ot-builtins.h
src/ostree/ot-main.c
src/ostree/ot-main.h

index e114690db3c6030def427c2fdc1ec6bd64de7c66..b8dccd6bb37d1a9fe4e6054e6828e2758de114f0 100644 (file)
 #include "ot-builtins.h"
 
 static OstreeCommand commands[] = {
-  { "admin", ostree_builtin_admin, OSTREE_BUILTIN_FLAG_NO_REPO },
-  { "cat", ostree_builtin_cat, 0 },
-  { "checkout", ostree_builtin_checkout, 0 },
-  { "checksum", ostree_builtin_checksum, OSTREE_BUILTIN_FLAG_NO_REPO },
-  { "commit", ostree_builtin_commit, 0 },
-  { "config", ostree_builtin_config, 0 },
-  { "diff", ostree_builtin_diff, 0 },
-  { "fsck", ostree_builtin_fsck, 0 },
-  { "init", ostree_builtin_init, OSTREE_BUILTIN_FLAG_NO_CHECK },
-  { "log", ostree_builtin_log, 0 },
-  { "ls", ostree_builtin_ls, 0 },
-  { "prune", ostree_builtin_prune, 0 },
-  { "pull-local", ostree_builtin_pull_local, 0 },
+  { "admin", ostree_builtin_admin },
+  { "cat", ostree_builtin_cat },
+  { "checkout", ostree_builtin_checkout },
+  { "checksum", ostree_builtin_checksum },
+  { "commit", ostree_builtin_commit },
+  { "config", ostree_builtin_config },
+  { "diff", ostree_builtin_diff },
+  { "fsck", ostree_builtin_fsck },
+  { "init", ostree_builtin_init },
+  { "log", ostree_builtin_log },
+  { "ls", ostree_builtin_ls },
+  { "prune", ostree_builtin_prune },
+  { "pull-local", ostree_builtin_pull_local },
 #ifdef HAVE_LIBSOUP 
-  { "pull", ostree_builtin_pull, 0 },
+  { "pull", ostree_builtin_pull },
 #endif
-  { "refs", ostree_builtin_refs, 0 },
-  { "remote", ostree_builtin_remote, 0 },
-  { "reset", ostree_builtin_reset, 0 },
-  { "rev-parse", ostree_builtin_rev_parse, 0 },
-  { "show", ostree_builtin_show, 0 },
-  { "static-delta", ostree_builtin_static_delta, 0 },
-  { "summary", ostree_builtin_summary, 0 },
+  { "refs", ostree_builtin_refs },
+  { "remote", ostree_builtin_remote },
+  { "reset", ostree_builtin_reset },
+  { "rev-parse", ostree_builtin_rev_parse },
+  { "show", ostree_builtin_show },
+  { "static-delta", ostree_builtin_static_delta },
+  { "summary", ostree_builtin_summary },
 #ifdef HAVE_LIBSOUP 
-  { "trivial-httpd", ostree_builtin_trivial_httpd, OSTREE_BUILTIN_FLAG_NO_REPO },
+  { "trivial-httpd", ostree_builtin_trivial_httpd },
 #endif
   { NULL }
 };
@@ -71,9 +71,11 @@ main (int    argc,
 
   setlocale (LC_ALL, "");
 
+  g_set_prgname (argv[0]);
+
   ret = ostree_run (argc, argv, commands, &error);
   if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
-    ostree_usage (argv, commands, TRUE);
+    ostree_usage (commands, TRUE);
 
   if (error != NULL)
     {
index 015dfe7aa1781487b616f8b7a11816f77f87b847..be9aaf328ac89199e2efd9bbc1d8ee17321ff3f0 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "config.h"
 
+#include "ot-main.h"
 #include "ot-admin-builtins.h"
 #include "ot-admin-functions.h"
 #include "ostree.h"
@@ -34,16 +35,15 @@ static GOptionEntry options[] = {
 };
 
 gboolean
-ot_admin_builtin_cleanup (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error)
+ot_admin_builtin_cleanup (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   GOptionContext *context;
+  gs_unref_object OstreeSysroot *sysroot = NULL;
   gboolean ret = FALSE;
 
   context = g_option_context_new ("Delete untagged deployments and repository objects");
 
-  g_option_context_add_main_entries (context, options, NULL);
-
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_admin_option_context_parse (context, options, &argc, &argv, &sysroot, cancellable, error))
     goto out;
 
   if (!ostree_sysroot_load (sysroot, cancellable, error))
index 3584dee1776c50092840014d9023694163443ffa..6c4327b79bb1115415ef41939fb90915a7e372f4 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "config.h"
 
+#include "ot-main.h"
 #include "ot-admin-builtins.h"
 #include "ot-admin-functions.h"
 #include "ostree.h"
@@ -49,11 +50,12 @@ static GOptionEntry options[] = {
 };
 
 gboolean
-ot_admin_builtin_deploy (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error)
+ot_admin_builtin_deploy (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   gboolean ret = FALSE;
   const char *refspec;
   GOptionContext *context;
+  gs_unref_object OstreeSysroot *sysroot = NULL;
   GKeyFile *origin = NULL;
   gs_unref_object OstreeRepo *repo = NULL;
   gs_unref_ptrarray GPtrArray *new_deployments = NULL;
@@ -64,9 +66,7 @@ ot_admin_builtin_deploy (int argc, char **argv, OstreeSysroot *sysroot, GCancell
 
   context = g_option_context_new ("REFSPEC - Checkout revision REFSPEC as the new default deployment");
 
-  g_option_context_add_main_entries (context, options, NULL);
-
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_admin_option_context_parse (context, options, &argc, &argv, &sysroot, cancellable, error))
     goto out;
 
   if (argc < 2)
index 2e9abc0f2dd5806e2be46c8cc208c8396a820004..55a8911084ce7358effdb1e39a7451627c991f32 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "config.h"
 
+#include "ot-main.h"
 #include "ot-admin-builtins.h"
 #include "ot-admin-functions.h"
 #include "ostree.h"
@@ -37,9 +38,10 @@ static GOptionEntry options[] = {
 };
 
 gboolean
-ot_admin_builtin_diff (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error)
+ot_admin_builtin_diff (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   GOptionContext *context;
+  gs_unref_object OstreeSysroot *sysroot = NULL;
   gboolean ret = FALSE;
   gs_unref_object OstreeDeployment *deployment = NULL;
   gs_unref_object GFile *deployment_dir = NULL;
@@ -53,7 +55,7 @@ ot_admin_builtin_diff (int argc, char **argv, OstreeSysroot *sysroot, GCancellab
 
   g_option_context_add_main_entries (context, options, NULL);
 
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_admin_option_context_parse (context, options, &argc, &argv, &sysroot, cancellable, error))
     goto out;
   
   if (!ostree_sysroot_load (sysroot, cancellable, error))
index 01114c5b27a3168f6dc21b4b8229c97e18f303d6..9fe46f4ca4612224e2a47ebdba075a1c52d72474 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "config.h"
 
+#include "ot-main.h"
 #include "ot-admin-builtins.h"
 #include "ot-admin-functions.h"
 #include "otutil.h"
@@ -34,9 +35,10 @@ static GOptionEntry options[] = {
 };
 
 gboolean
-ot_admin_builtin_init_fs (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error)
+ot_admin_builtin_init_fs (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   GOptionContext *context;
+  gs_unref_object OstreeSysroot *sysroot = NULL;
   gboolean ret = FALSE;
   gs_unref_object GFile *dir = NULL;
   gs_unref_object GFile *child = NULL;
@@ -45,9 +47,8 @@ ot_admin_builtin_init_fs (int argc, char **argv, OstreeSysroot *sysroot, GCancel
   const char *normal_toplevels[] = {"boot", "dev", "home", "proc", "run", "sys"};
 
   context = g_option_context_new ("PATH - Initialize a root filesystem");
-  g_option_context_add_main_entries (context, options, NULL);
 
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_admin_option_context_parse (context, options, &argc, &argv, &sysroot, cancellable, error))
     goto out;
 
   if (argc < 2)
index 7a17dd3b190a20e36f93e0e8fd014fdfb6ea3f91..ba4d9b428018a6ff15c6d1a6a935bdbcaeecc6f5 100644 (file)
@@ -32,7 +32,7 @@
 
 typedef struct {
   const char *name;
-  gboolean (*fn) (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error);
+  gboolean (*fn) (int argc, char **argv, GCancellable *cancellable, GError **error);
 } OstreeAdminInstUtilCommand;
 
 static OstreeAdminInstUtilCommand admin_instutil_subcommands[] = {
@@ -44,101 +44,62 @@ static OstreeAdminInstUtilCommand admin_instutil_subcommands[] = {
   { NULL, NULL }
 };
 
+static GOptionContext *
+ostree_admin_instutil_option_context_new_with_commands (void)
+{
+  OstreeAdminInstUtilCommand *command = admin_instutil_subcommands;
+  GOptionContext *context;
+  GString *summary;
+
+  context = g_option_context_new ("COMMAND");
+
+  summary = g_string_new ("Builtin \"admin instutil\" Commands:");
+
+  while (command->name != NULL)
+    {
+      g_string_append_printf (summary, "\n  %s", command->name);
+      command++;
+    }
+
+  g_option_context_set_summary (context, summary->str);
+
+  g_string_free (summary, TRUE);
+
+  return context;
+}
+
 gboolean
-ot_admin_builtin_instutil (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error)
+ot_admin_builtin_instutil (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   gboolean ret = FALSE;
   OstreeAdminInstUtilCommand *subcommand;
   const char *subcommand_name = NULL;
-  gboolean want_help = FALSE;
-  int in, out, i;
-  gboolean skip;
+  gs_free char *prgname = NULL;
+  int in, out;
 
   for (in = 1, out = 1; in < argc; in++, out++)
     {
       /* The non-option is the command, take it out of the arguments */
       if (argv[in][0] != '-')
         {
-          skip = (subcommand_name == NULL);
           if (subcommand_name == NULL)
-            subcommand_name = argv[in];
-        }
-
-      /* The global long options */
-      else if (argv[in][1] == '-')
-        {
-          skip = FALSE;
-
-          if (g_str_equal (argv[in], "--"))
-            {
-              break;
-            }
-          else if (g_str_equal (argv[in], "--help"))
-            {
-              want_help = TRUE;
-            }
-          else if (subcommand_name == NULL)
             {
-              g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                           "Unknown or invalid admin instutil option: %s", argv[in]);
-              goto out;
+              subcommand_name = argv[in];
+              out--;
+              continue;
             }
         }
 
-      /* The global short options */
-      else
+      else if (g_str_equal (argv[in], "--"))
         {
-          skip = FALSE;
-          for (i = 1; argv[in][i] != '\0'; i++)
-            {
-              switch (argv[in][i])
-              {
-                case 'h':
-                  want_help = TRUE;
-                  break;
-
-                default:
-                  if (subcommand_name == NULL)
-                    {
-                      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                                   "Unknown or invalid admin instutil option: %s", argv[in]);
-                      goto out;
-                    }
-                  break;
-              }
-            }
+          break;
         }
 
-      /* Skipping this argument? */
-      if (skip)
-        out--;
-      else
-        argv[out] = argv[in];
+      argv[out] = argv[in];
     }
 
   argc = out;
 
-  if (subcommand_name == NULL)
-    {
-      void (*print_func) (const gchar *format, ...) = want_help ? g_print : g_printerr;
-
-      subcommand = admin_instutil_subcommands;
-      print_func ("usage: ostree admin instutil COMMAND [options]\n");
-      print_func ("Builtin commands:\n");
-      while (subcommand->name)
-        {
-          print_func ("  %s\n", subcommand->name);
-          subcommand++;
-        }
-
-      if (want_help)
-        ret = TRUE;
-      else
-        g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                             "No command specified");
-      goto out;
-    }
-
   subcommand = admin_instutil_subcommands;
   while (subcommand->name)
     {
@@ -149,14 +110,38 @@ ot_admin_builtin_instutil (int argc, char **argv, OstreeSysroot *sysroot, GCance
 
   if (!subcommand->name)
     {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
-                   "Unknown admin instutil command '%s'", subcommand_name);
+      GOptionContext *context;
+      gs_free char *help;
+
+      context = ostree_admin_instutil_option_context_new_with_commands ();
+
+      /* This will not return for some options (e.g. --version). */
+      if (ostree_admin_option_context_parse (context, NULL, &argc, &argv, NULL, cancellable, error))
+        {
+          if (subcommand_name == NULL)
+            {
+              g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                                   "No \"admin instutil\" subcommand specified");
+            }
+          else
+            {
+              g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                           "Unknown \"admin instutil\" subcommand '%s'", subcommand_name);
+            }
+        }
+
+      help = g_option_context_get_help (context, FALSE, NULL);
+      g_printerr ("%s", help);
+
+      g_option_context_free (context);
+
       goto out;
     }
 
-  g_set_prgname (g_strdup_printf ("ostree admin instutil %s", subcommand_name));
+  prgname = g_strdup_printf ("%s %s", g_get_prgname (), subcommand_name);
+  g_set_prgname (prgname);
 
-  if (!subcommand->fn (argc, argv, sysroot, cancellable, error))
+  if (!subcommand->fn (argc, argv, cancellable, error))
     goto out;
  
   ret = TRUE;
index 19ed4a1c526f3c2da0843cbcca22c49866887bf9..a94837e811f872a09580fad22c617fbd9b16dcc8 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "config.h"
 
+#include "ot-main.h"
 #include "ot-admin-builtins.h"
 #include "ot-admin-functions.h"
 #include "otutil.h"
@@ -34,18 +35,18 @@ static GOptionEntry options[] = {
 };
 
 gboolean
-ot_admin_builtin_os_init (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error)
+ot_admin_builtin_os_init (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   GOptionContext *context;
+  gs_unref_object OstreeSysroot *sysroot = NULL;
   gboolean ret = FALSE;
   const char *osname = NULL;
   gs_unref_object GFile *deploy_dir = NULL;
   gs_unref_object GFile *dir = NULL;
 
   context = g_option_context_new ("OSNAME - Initialize empty state for given operating system");
-  g_option_context_add_main_entries (context, options, NULL);
 
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_admin_option_context_parse (context, options, &argc, &argv, &sysroot, cancellable, error))
     goto out;
 
   if (!ostree_sysroot_ensure_initialized (sysroot, cancellable, error))
index 9ce2f433441ace9da4b0ad79e51f9465315294e1..382c5e61513bb9e05ec1b71cd69636e44e93cb8d 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "config.h"
 
+#include "ot-main.h"
 #include "ot-admin-builtins.h"
 #include "ot-admin-functions.h"
 #include "ostree.h"
@@ -49,9 +50,10 @@ version_of_commit (OstreeRepo *repo, const char *checksum)
 }
 
 gboolean
-ot_admin_builtin_status (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error)
+ot_admin_builtin_status (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   GOptionContext *context;
+  gs_unref_object OstreeSysroot *sysroot = NULL;
   gboolean ret = FALSE;
   gs_unref_object OstreeRepo *repo = NULL;
   OstreeDeployment *booted_deployment = NULL;
@@ -60,9 +62,7 @@ ot_admin_builtin_status (int argc, char **argv, OstreeSysroot *sysroot, GCancell
 
   context = g_option_context_new ("List deployments");
 
-  g_option_context_add_main_entries (context, options, NULL);
-
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_admin_option_context_parse (context, options, &argc, &argv, &sysroot, cancellable, error))
     goto out;
 
   if (!ostree_sysroot_load (sysroot, cancellable, error))
index 3900b81c1b7d3b96a49b7bb9dcf186a0f1787755..2f6c334344e7ff00c3738d74262e9448ffac7a20 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "config.h"
 
+#include "ot-main.h"
 #include "ot-admin-builtins.h"
 #include "ot-admin-functions.h"
 #include "ot-builtins-common.h"
@@ -40,10 +41,11 @@ static GOptionEntry options[] = {
 };
 
 gboolean
-ot_admin_builtin_switch (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error)
+ot_admin_builtin_switch (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   gboolean ret = FALSE;
   GOptionContext *context;
+  gs_unref_object OstreeSysroot *sysroot = NULL;
   const char *new_provided_refspec = NULL;
   gs_unref_object OstreeRepo *repo = NULL;
   gs_free char *origin_refspec = NULL;
@@ -66,9 +68,8 @@ ot_admin_builtin_switch (int argc, char **argv, OstreeSysroot *sysroot, GCancell
   GKeyFile *new_origin = NULL;
 
   context = g_option_context_new ("REF - Construct new tree from current origin and deploy it, if it changed");
-  g_option_context_add_main_entries (context, options, NULL);
 
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_admin_option_context_parse (context, options, &argc, &argv, &sysroot, cancellable, error))
     goto out;
 
   if (argc < 2)
index 055209db327481ebb69af5704ab7a13ad79f70a3..edf89bf4242b4cedeb64ee884d11b84e076bd576 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <stdlib.h>
 
+#include "ot-main.h"
 #include "ot-admin-builtins.h"
 #include "ot-admin-functions.h"
 #include "ostree.h"
@@ -32,10 +33,11 @@ static GOptionEntry options[] = {
 };
 
 gboolean
-ot_admin_builtin_undeploy (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error)
+ot_admin_builtin_undeploy (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   gboolean ret = FALSE;
   GOptionContext *context;
+  gs_unref_object OstreeSysroot *sysroot = NULL;
   const char *deploy_index_str;
   int deploy_index;
   gs_unref_ptrarray GPtrArray *current_deployments = NULL;
@@ -44,9 +46,7 @@ ot_admin_builtin_undeploy (int argc, char **argv, OstreeSysroot *sysroot, GCance
 
   context = g_option_context_new ("INDEX - Delete deployment INDEX");
 
-  g_option_context_add_main_entries (context, options, NULL);
-
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_admin_option_context_parse (context, options, &argc, &argv, &sysroot, cancellable, error))
     goto out;
 
   if (argc < 2)
index ffb93d4a736f9b7437409e3b86aca11c386cebde..1dff0a5307628afb05eb9641874f9f35aef1ffff 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "config.h"
 
+#include "ot-main.h"
 #include "ot-admin-builtins.h"
 #include "ot-admin-functions.h"
 #include "ot-builtins-common.h"
@@ -45,10 +46,11 @@ static GOptionEntry options[] = {
 };
 
 gboolean
-ot_admin_builtin_upgrade (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error)
+ot_admin_builtin_upgrade (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   gboolean ret = FALSE;
   GOptionContext *context;
+  gs_unref_object OstreeSysroot *sysroot = NULL;
   gs_unref_object OstreeSysrootUpgrader *upgrader = NULL;
   gs_free char *origin_remote = NULL;
   gs_free char *origin_ref = NULL;
@@ -65,9 +67,8 @@ ot_admin_builtin_upgrade (int argc, char **argv, OstreeSysroot *sysroot, GCancel
   OstreeSysrootUpgraderPullFlags upgraderpullflags = 0;
 
   context = g_option_context_new ("Construct new tree from current origin and deploy it, if it changed");
-  g_option_context_add_main_entries (context, options, NULL);
 
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_admin_option_context_parse (context, options, &argc, &argv, &sysroot, cancellable, error))
     goto out;
 
   if (!ostree_sysroot_load (sysroot, cancellable, error))
index a4e5754f121ab00c8f224471c2bc01e864b479a5..9858f5b5b594792e82f9dad326f184bec26336a0 100644 (file)
 
 G_BEGIN_DECLS
 
-gboolean ot_admin_builtin_selinux_ensure_labeled (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error);
-gboolean ot_admin_builtin_os_init (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error);
-gboolean ot_admin_builtin_install (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error);
-gboolean ot_admin_builtin_instutil (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error);
-gboolean ot_admin_builtin_init_fs (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error);
-gboolean ot_admin_builtin_undeploy (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error);
-gboolean ot_admin_builtin_deploy (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error);
-gboolean ot_admin_builtin_cleanup (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error);
-gboolean ot_admin_builtin_status (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error);
-gboolean ot_admin_builtin_diff (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error);
-gboolean ot_admin_builtin_switch (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error);
-gboolean ot_admin_builtin_upgrade (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error);
+gboolean ot_admin_builtin_selinux_ensure_labeled (int argc, char **argv, GCancellable *cancellable, GError **error);
+gboolean ot_admin_builtin_os_init (int argc, char **argv, GCancellable *cancellable, GError **error);
+gboolean ot_admin_builtin_install (int argc, char **argv, GCancellable *cancellable, GError **error);
+gboolean ot_admin_builtin_instutil (int argc, char **argv, GCancellable *cancellable, GError **error);
+gboolean ot_admin_builtin_init_fs (int argc, char **argv, GCancellable *cancellable, GError **error);
+gboolean ot_admin_builtin_undeploy (int argc, char **argv, GCancellable *cancellable, GError **error);
+gboolean ot_admin_builtin_deploy (int argc, char **argv, GCancellable *cancellable, GError **error);
+gboolean ot_admin_builtin_cleanup (int argc, char **argv, GCancellable *cancellable, GError **error);
+gboolean ot_admin_builtin_status (int argc, char **argv, GCancellable *cancellable, GError **error);
+gboolean ot_admin_builtin_diff (int argc, char **argv, GCancellable *cancellable, GError **error);
+gboolean ot_admin_builtin_switch (int argc, char **argv, GCancellable *cancellable, GError **error);
+gboolean ot_admin_builtin_upgrade (int argc, char **argv, GCancellable *cancellable, GError **error);
 
 G_END_DECLS
 
index 4aa58d01a6a6e3c52a09216661e7c21c1a119b05..617b16085b1ab542a2717ade99f688a009d15b57 100644 (file)
@@ -23,6 +23,7 @@
 #include <string.h>
 #include <glib-unix.h>
 
+#include "ot-main.h"
 #include "ot-admin-instutil-builtins.h"
 #include "ostree-cmdprivate.h"
 
@@ -33,7 +34,7 @@ static GOptionEntry options[] = {
 };
 
 gboolean
-ot_admin_instutil_builtin_grub2_generate (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error)
+ot_admin_instutil_builtin_grub2_generate (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   gboolean ret = FALSE;
   guint bootversion;
@@ -41,13 +42,12 @@ ot_admin_instutil_builtin_grub2_generate (int argc, char **argv, OstreeSysroot *
   gs_unref_object OstreeSePolicy *sepolicy = NULL;
   gs_unref_ptrarray GPtrArray *deployments = NULL;
   GOptionContext *context = NULL;
+  gs_unref_object OstreeSysroot *sysroot = NULL;
   gs_unref_object GFile *deployment_path = NULL;
 
   context = g_option_context_new ("[BOOTVERSION] - generate GRUB2 configuration from given BLS entries");
 
-  g_option_context_add_main_entries (context, options, NULL);
-
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_admin_option_context_parse (context, options, &argc, &argv, &sysroot, cancellable, error))
     goto out;
 
   if (argc >= 2)
index 8bd0c8a1aa27a64a92c3c704239d0679b3a95e37..7e9ca0600062ab5dee0e16259597a735085c65eb 100644 (file)
@@ -23,6 +23,7 @@
 #include <string.h>
 #include <glib-unix.h>
 
+#include "ot-main.h"
 #include "ot-admin-instutil-builtins.h"
 
 #include "otutil.h"
@@ -178,7 +179,7 @@ static GOptionEntry options[] = {
 };
 
 gboolean
-ot_admin_instutil_builtin_selinux_ensure_labeled (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error)
+ot_admin_instutil_builtin_selinux_ensure_labeled (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   gboolean ret = FALSE;
   const char *policy_name;
@@ -188,13 +189,12 @@ ot_admin_instutil_builtin_selinux_ensure_labeled (int argc, char **argv, OstreeS
   gs_unref_ptrarray GPtrArray *deployments = NULL;
   OstreeDeployment *first_deployment;
   GOptionContext *context = NULL;
+  gs_unref_object OstreeSysroot *sysroot = NULL;
   gs_unref_object GFile *deployment_path = NULL;
 
   context = g_option_context_new ("[SUBPATH PREFIX] - relabel all or part of a deployment");
 
-  g_option_context_add_main_entries (context, options, NULL);
-
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_admin_option_context_parse (context, options, &argc, &argv, &sysroot, cancellable, error))
     goto out;
 
   if (!ostree_sysroot_load (sysroot, cancellable, error))
index b683f19cff268a9b65950025e1d10643ffc53113..cef524284a2479b04017167badf89b04ae8d2aee 100644 (file)
@@ -23,6 +23,7 @@
 #include <string.h>
 #include <glib-unix.h>
 
+#include "ot-main.h"
 #include "ot-admin-instutil-builtins.h"
 
 #include "otutil.h"
@@ -43,20 +44,19 @@ static GOptionEntry options[] = {
 };
 
 gboolean
-ot_admin_instutil_builtin_set_kargs (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error)
+ot_admin_instutil_builtin_set_kargs (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   gboolean ret = FALSE;
   guint i;
   gs_unref_ptrarray GPtrArray *deployments = NULL;
   OstreeDeployment *first_deployment = NULL;
   GOptionContext *context = NULL;
+  gs_unref_object OstreeSysroot *sysroot = NULL;
   __attribute__((cleanup(_ostree_kernel_args_cleanup))) OstreeKernelArgs *kargs = NULL;
 
   context = g_option_context_new ("ARGS - set new kernel command line arguments");
 
-  g_option_context_add_main_entries (context, options, NULL);
-
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_admin_option_context_parse (context, options, &argc, &argv, &sysroot, cancellable, error))
     goto out;
 
   if (!ostree_sysroot_load (sysroot, cancellable, error))
index 5442eb527ce3439cd52566656d277cfe7020c323..16abe424c0c3933585413ba9e9e5ea5d3ced404a 100644 (file)
@@ -24,9 +24,9 @@
 
 G_BEGIN_DECLS
 
-gboolean ot_admin_instutil_builtin_selinux_ensure_labeled (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error);
-gboolean ot_admin_instutil_builtin_set_kargs (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error);
-gboolean ot_admin_instutil_builtin_grub2_generate (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error);
+gboolean ot_admin_instutil_builtin_selinux_ensure_labeled (int argc, char **argv, GCancellable *cancellable, GError **error);
+gboolean ot_admin_instutil_builtin_set_kargs (int argc, char **argv, GCancellable *cancellable, GError **error);
+gboolean ot_admin_instutil_builtin_grub2_generate (int argc, char **argv, GCancellable *cancellable, GError **error);
 
 G_END_DECLS
 
index 2165656ca695fe3b89afb4f01581e3838ca2e2b3..47cf1b74ed6c0a2921219074de94598577a52d6f 100644 (file)
@@ -34,7 +34,7 @@
 
 typedef struct {
   const char *name;
-  gboolean (*fn) (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error);
+  gboolean (*fn) (int argc, char **argv, GCancellable *cancellable, GError **error);
 } OstreeAdminCommand;
 
 static OstreeAdminCommand admin_subcommands[] = {
@@ -51,19 +51,38 @@ static OstreeAdminCommand admin_subcommands[] = {
   { NULL, NULL }
 };
 
+static GOptionContext *
+ostree_admin_option_context_new_with_commands (void)
+{
+  OstreeAdminCommand *command = admin_subcommands;
+  GOptionContext *context;
+  GString *summary;
+
+  context = g_option_context_new ("--print-current-dir|COMMAND");
+
+  summary = g_string_new ("Builtin \"admin\" Commands:");
+
+  while (command->name != NULL)
+    {
+      g_string_append_printf (summary, "\n  %s", command->name);
+      command++;
+    }
+
+  g_option_context_set_summary (context, summary->str);
+
+  g_string_free (summary, TRUE);
+
+  return context;
+}
+
 gboolean
-ostree_builtin_admin (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error)
+ostree_builtin_admin (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   gboolean ret = FALSE;
-  const char *opt_sysroot = "/";
   const char *subcommand_name = NULL;
   OstreeAdminCommand *subcommand;
-  gs_unref_object GFile *sysroot_path = NULL;
-  gs_unref_object OstreeSysroot *sysroot = NULL;
-  gboolean want_help = FALSE;
-  gboolean want_current_dir = FALSE;
-  int in, out, i;
-  gboolean skip;
+  gs_free char *prgname = NULL;
+  int in, out;
 
   /*
    * Parse the global options. We rearrange the options as
@@ -76,148 +95,66 @@ ostree_builtin_admin (int argc, char **argv, OstreeRepo *repo, GCancellable *can
       /* The non-option is the command, take it out of the arguments */
       if (argv[in][0] != '-')
         {
-          skip = (subcommand_name == NULL);
           if (subcommand_name == NULL)
-            subcommand_name = argv[in];
-        }
-
-      /* The global long options */
-      else if (argv[in][1] == '-')
-        {
-          skip = FALSE;
-
-          if (g_str_equal (argv[in], "--"))
-            {
-              break;
-            }
-          else if (g_str_equal (argv[in], "--help"))
-            {
-              want_help = TRUE;
-            }
-          else if (g_str_equal (argv[in], "--print-current-dir"))
-            {
-              want_current_dir = TRUE;
-            }
-          else if (g_str_equal (argv[in], "--sysroot") && in + 1 < argc)
             {
-              opt_sysroot = argv[in + 1];
-              skip = TRUE;
-              in++;
-            }
-          else if (g_str_has_prefix (argv[in], "--sysroot="))
-            {
-              opt_sysroot = argv[in] + 10;
-              skip = TRUE;
-            }
-          else if (subcommand_name == NULL)
-            {
-              g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                           "Unknown or invalid admin option: %s", argv[in]);
-              goto out;
+              subcommand_name = argv[in];
+              out--;
+              continue;
             }
         }
 
-      /* The global short options */
-      else
+      else if (g_str_equal (argv[in], "--"))
         {
-          skip = FALSE;
-          for (i = 1; argv[in][i] != '\0'; i++)
-            {
-              switch (argv[in][i])
-              {
-                case 'h':
-                  want_help = TRUE;
-                  break;
-
-                default:
-                  if (subcommand_name == NULL)
-                    {
-                      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                                   "Unknown or invalid admin option: %s", argv[in]);
-                      goto out;
-                    }
-                  break;
-              }
-            }
+          break;
         }
 
-      /* Skipping this argument? */
-      if (skip)
-        out--;
-      else
-        argv[out] = argv[in];
+      argv[out] = argv[in];
     }
 
   argc = out;
 
-  if (subcommand_name == NULL && (want_help || !want_current_dir))
+  subcommand = admin_subcommands;
+  while (subcommand->name)
     {
-      void (*print_func) (const gchar *format, ...) = want_help ? g_print : g_printerr;
-
-      subcommand = admin_subcommands;
-      print_func ("usage: ostree admin [--sysroot=PATH] [--print-current-dir|COMMAND] [options]\n");
-      print_func ("Builtin commands:\n");
-      while (subcommand->name)
-        {
-          print_func ("  %s\n", subcommand->name);
-          subcommand++;
-        }
-
-      if (want_help)
-        ret = TRUE;
-      else
-        g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                             "No command specified");
-      goto out;
+      if (g_strcmp0 (subcommand_name, subcommand->name) == 0)
+        break;
+      subcommand++;
     }
 
-  sysroot_path = g_file_new_for_path (opt_sysroot);
-  sysroot = ostree_sysroot_new (sysroot_path);
-
-  if (want_current_dir)
+  if (!subcommand->name)
     {
-      gs_unref_ptrarray GPtrArray *deployments = NULL;
-      OstreeDeployment *first_deployment;
-      gs_unref_object GFile *deployment_file = NULL;
-      gs_free char *deployment_path = NULL;
+      GOptionContext *context;
+      gs_free char *help;
 
-      if (!ostree_sysroot_load (sysroot, cancellable, error))
-        goto out;
+      context = ostree_admin_option_context_new_with_commands ();
 
-      deployments = ostree_sysroot_get_deployments (sysroot);
-      if (deployments->len == 0)
+      /* This will not return for some options (e.g. --version). */
+      if (ostree_admin_option_context_parse (context, NULL, &argc, &argv, NULL, cancellable, error))
         {
-          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                       "Unable to find a deployment in sysroot");
-          goto out;
+          if (subcommand_name == NULL)
+            {
+              g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                                   "No \"admin\" subcommand specified");
+            }
+          else
+            {
+              g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                           "Unknown \"admin\" subcommand '%s'", subcommand_name);
+            }
         }
-      first_deployment = deployments->pdata[0];
-      deployment_file = ostree_sysroot_get_deployment_directory (sysroot, first_deployment);
-      deployment_path = g_file_get_path (deployment_file);
 
-      g_print ("%s\n", deployment_path);
-      ret = TRUE;
-      goto out;
-    }
+      help = g_option_context_get_help (context, FALSE, NULL);
+      g_printerr ("%s", help);
 
-  subcommand = admin_subcommands;
-  while (subcommand->name)
-    {
-      if (g_strcmp0 (subcommand_name, subcommand->name) == 0)
-        break;
-      subcommand++;
-    }
+      g_option_context_free (context);
 
-  if (!subcommand->name)
-    {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
-                   "Unknown admin command '%s'", subcommand_name);
       goto out;
     }
 
-  g_set_prgname (g_strdup_printf ("ostree admin %s", subcommand_name));
+  prgname = g_strdup_printf ("%s %s", g_get_prgname (), subcommand_name);
+  g_set_prgname (prgname);
 
-  if (!subcommand->fn (argc, argv, sysroot, cancellable, error))
+  if (!subcommand->fn (argc, argv, cancellable, error))
     goto out;
  
   ret = TRUE;
index 92d4c840edac7ac669e093eb7dfd401fe65006e8..721f992a1f74bfa7d1c648fce7cd4dde8a13236c 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "config.h"
 
+#include "ot-main.h"
 #include "ot-builtins.h"
 #include "ostree.h"
 #include "otutil.h"
@@ -55,9 +56,10 @@ cat_one_file (GFile         *f,
 }
 
 gboolean
-ostree_builtin_cat (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error)
+ostree_builtin_cat (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   GOptionContext *context;
+  gs_unref_object OstreeRepo *repo = NULL;
   gboolean ret = FALSE;
   int i;
   const char *rev;
@@ -66,9 +68,8 @@ ostree_builtin_cat (int argc, char **argv, OstreeRepo *repo, GCancellable *cance
   gs_unref_object GFile *f = NULL;
 
   context = g_option_context_new ("COMMIT PATH... - Concatenate contents of files");
-  g_option_context_add_main_entries (context, options, NULL);
 
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error))
     goto out;
 
   if (argc <= 2)
index 3f7761922d968ea9ee85ea70bccdd99f5dcfce63..b3284ef8a7d77d7a9b65db231335407588dcd9f9 100644 (file)
@@ -25,6 +25,7 @@
 #include <string.h>
 #include <gio/gunixinputstream.h>
 
+#include "ot-main.h"
 #include "ot-builtins.h"
 #include "ostree.h"
 #include "otutil.h"
@@ -170,9 +171,10 @@ process_many_checkouts (OstreeRepo         *repo,
 }
 
 gboolean
-ostree_builtin_checkout (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error)
+ostree_builtin_checkout (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   GOptionContext *context;
+  gs_unref_object OstreeRepo *repo = NULL;
   gboolean ret = FALSE;
   const char *commit;
   const char *destination;
@@ -180,9 +182,8 @@ ostree_builtin_checkout (int argc, char **argv, OstreeRepo *repo, GCancellable *
   gs_unref_object GFile *checkout_target = NULL;
 
   context = g_option_context_new ("COMMIT [DESTINATION] - Check out a commit into a filesystem tree");
-  g_option_context_add_main_entries (context, options, NULL);
 
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error))
     goto out;
 
   if (argc < 2)
index e7d5dd87578019600a886a983909344f16db6066..5c534f849df0f4fc6b97b601aa89521aa3be4c73 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "config.h"
 
+#include "ot-main.h"
 #include "ot-builtins.h"
 #include "ostree.h"
 #include "libgsystem.h"
@@ -56,7 +57,7 @@ on_checksum_received (GObject    *obj,
 }
 
 gboolean
-ostree_builtin_checksum (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error)
+ostree_builtin_checksum (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   GOptionContext *context;
   gboolean ret = FALSE;
@@ -64,9 +65,8 @@ ostree_builtin_checksum (int argc, char **argv, OstreeRepo *repo, GCancellable *
   AsyncChecksumData data = { 0, };
 
   context = g_option_context_new ("PATH - Checksum a file or directory");
-  g_option_context_add_main_entries (context, options, NULL);
 
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NO_REPO, NULL, cancellable, error))
     goto out;
 
   if (argc > 1)
index eda556e9cca949d18f3189d7f1c4fc5e9c73c6f1..47c9b7c32401eaf0d2e645332ddc7c59ecc79fee 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "config.h"
 
+#include "ot-main.h"
 #include "ot-builtins.h"
 #include "ot-editor.h"
 #include "ostree.h"
@@ -309,9 +310,10 @@ parse_keyvalue_strings (char             **strings,
 }
 
 gboolean
-ostree_builtin_commit (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error)
+ostree_builtin_commit (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   GOptionContext *context;
+  gs_unref_object OstreeRepo *repo = NULL;
   gboolean ret = FALSE;
   gboolean skip_commit = FALSE;
   gs_unref_object GFile *arg = NULL;
@@ -328,9 +330,8 @@ ostree_builtin_commit (int argc, char **argv, OstreeRepo *repo, GCancellable *ca
   OstreeRepoTransactionStats stats;
 
   context = g_option_context_new ("[PATH] - Commit a new revision");
-  g_option_context_add_main_entries (context, options, NULL);
 
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error))
     goto out;
 
   if (opt_statoverride_file)
@@ -563,7 +564,8 @@ ostree_builtin_commit (int argc, char **argv, OstreeRepo *repo, GCancellable *ca
 
   ret = TRUE;
  out:
-  ostree_repo_abort_transaction (repo, cancellable, NULL);
+  if (repo)
+    ostree_repo_abort_transaction (repo, cancellable, NULL);
   if (context)
     g_option_context_free (context);
   if (modifier)
index 56ddf86ee8a4e9564f744e22902cb782c0455baf..235e498518b2f4cd6d200ab1db1956378696d69c 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "config.h"
 
+#include "ot-main.h"
 #include "ot-builtins.h"
 #include "ostree.h"
 #include "otutil.h"
@@ -52,9 +53,10 @@ split_key_string (const char   *k,
 }
 
 gboolean
-ostree_builtin_config (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error)
+ostree_builtin_config (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   GOptionContext *context = NULL;
+  gs_unref_object OstreeRepo *repo = NULL;
   gboolean ret = FALSE;
   const char *op;
   const char *section_key;
@@ -64,9 +66,8 @@ ostree_builtin_config (int argc, char **argv, OstreeRepo *repo, GCancellable *ca
   GKeyFile *config = NULL;
 
   context = g_option_context_new ("- Change configuration settings");
-  g_option_context_add_main_entries (context, options, NULL);
 
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error))
     goto out;
 
   if (argc < 2)
index 65d55be2564fd7a868267ba57fe52e29ac06b5e1..7948c5da38655e9aa87561a2651da0df11e32233 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "config.h"
 
+#include "ot-main.h"
 #include "ot-builtins.h"
 #include "ostree.h"
 #include "otutil.h"
@@ -115,10 +116,11 @@ object_set_total_size (OstreeRepo    *repo,
 }
 
 gboolean
-ostree_builtin_diff (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error)
+ostree_builtin_diff (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   gboolean ret = FALSE;
   GOptionContext *context;
+  gs_unref_object OstreeRepo *repo = NULL;
   const char *src;
   const char *target;
   gs_free char *src_prev = NULL;
@@ -131,7 +133,7 @@ ostree_builtin_diff (int argc, char **argv, OstreeRepo *repo, GCancellable *canc
   context = g_option_context_new ("REV TARGETDIR - Compare directory TARGETDIR against revision REV");
   g_option_context_add_main_entries (context, options, NULL);
 
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error))
     goto out;
 
   if (argc < 2)
index 79bb5f2b932c8844f63a2516b978bf2085148a1a..333614cd7465592e40c772d0be6e8a99d6b61475 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "config.h"
 
+#include "ot-main.h"
 #include "ot-builtins.h"
 #include "ostree.h"
 #include "otutil.h"
@@ -233,10 +234,11 @@ fsck_reachable_objects_from_commits (OstreeRepo            *repo,
 }
 
 gboolean
-ostree_builtin_fsck (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error)
+ostree_builtin_fsck (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   gboolean ret = FALSE;
   GOptionContext *context;
+  gs_unref_object OstreeRepo *repo = NULL;
   GHashTableIter hash_iter;
   gpointer key, value;
   gboolean found_corruption = FALSE;
@@ -244,9 +246,8 @@ ostree_builtin_fsck (int argc, char **argv, OstreeRepo *repo, GCancellable *canc
   gs_unref_hashtable GHashTable *commits = NULL;
 
   context = g_option_context_new ("- Check the repository for consistency");
-  g_option_context_add_main_entries (context, options, NULL);
 
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error))
     goto out;
 
   if (!opt_quiet)
index d57ed5c58e3b8ed67b16843f148b368ea4eab30c..9aceda50dc067bada52d1f54f8603485ab50c229 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "config.h"
 
+#include "ot-main.h"
 #include "ot-builtins.h"
 #include "ostree.h"
 #include "libgsystem.h"
@@ -34,16 +35,16 @@ static GOptionEntry options[] = {
 };
 
 gboolean
-ostree_builtin_init (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error)
+ostree_builtin_init (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   GOptionContext *context = NULL;
+  gs_unref_object OstreeRepo *repo = NULL;
   gboolean ret = FALSE;
   OstreeRepoMode mode;
 
   context = g_option_context_new ("- Initialize a new empty repository");
-  g_option_context_add_main_entries (context, options, NULL);
 
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NO_CHECK, &repo, cancellable, error))
     goto out;
 
   if (!ostree_repo_mode_from_string (opt_mode, &mode, error))
index 89445cd90d8c5da8cdd74ccbd9d6c90f4df9be59..5147adb8476c19eaec48e048a7113ac5216e33b6 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "config.h"
 
+#include "ot-main.h"
 #include "ot-builtins.h"
 #include "ot-dump.h"
 #include "ostree.h"
@@ -77,20 +78,19 @@ out:
 gboolean
 ostree_builtin_log (int           argc,
                     char        **argv,
-                    OstreeRepo   *repo,
                     GCancellable *cancellable,
                     GError      **error)
 {
   GOptionContext *context;
+  gs_unref_object OstreeRepo *repo = NULL;
   gboolean ret = FALSE;
   const char *rev;
   gs_free char *checksum = NULL;
   OstreeDumpFlags flags = OSTREE_DUMP_NONE;
 
   context = g_option_context_new ("REF - Show log starting at commit or ref");
-  g_option_context_add_main_entries (context, options, NULL);
 
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error))
     goto out;
 
   if (opt_raw)
index f0a85be53290d1946f3f6ab803c5328afdb0c8c5..1fce500391bc5247ec37ee7a49f7879261e9df65 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "config.h"
 
+#include "ot-main.h"
 #include "ot-builtins.h"
 #include "ostree.h"
 #include "ostree-repo-file.h"
@@ -239,18 +240,18 @@ print_one_argument (OstreeRepo   *repo,
 }
 
 gboolean
-ostree_builtin_ls (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error)
+ostree_builtin_ls (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   GOptionContext *context;
+  gs_unref_object OstreeRepo *repo = NULL;
   gboolean ret = FALSE;
   const char *rev;
   int i;
   gs_unref_object GFile *root = NULL;
 
   context = g_option_context_new ("COMMIT [PATH...] - List file paths");
-  g_option_context_add_main_entries (context, options, NULL);
 
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error))
     goto out;
 
   if (argc <= 1)
index e483bf59ffd6a413dc1192dc168d7dadf903a615..cd05b2f39a0a4feab61989b1e535fd15522269a6 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "config.h"
 
+#include "ot-main.h"
 #include "ot-builtins.h"
 #include "ostree.h"
 #include "libgsystem.h"
@@ -38,10 +39,11 @@ static GOptionEntry options[] = {
 };
 
 gboolean
-ostree_builtin_prune (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error)
+ostree_builtin_prune (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   gboolean ret = FALSE;
   GOptionContext *context;
+  gs_unref_object OstreeRepo *repo = NULL;
   gs_free char *formatted_freed_size = NULL;
   OstreeRepoPruneFlags pruneflags = 0;
   gint n_objects_total;
@@ -49,9 +51,8 @@ ostree_builtin_prune (int argc, char **argv, OstreeRepo *repo, GCancellable *can
   guint64 objsize_total;
 
   context = g_option_context_new ("- Search for unreachable objects");
-  g_option_context_add_main_entries (context, options, NULL);
 
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error))
     goto out;
 
   if (opt_refs_only)
index bd9773b70fef3b7706dc2898725b82c0cbcf42e4..808773d5f83a2196310f489345592f4134edac46 100644 (file)
@@ -25,6 +25,7 @@
 #include <unistd.h>
 #include <stdlib.h>
 
+#include "ot-main.h"
 #include "ot-builtins.h"
 #include "ostree.h"
 #include "otutil.h"
@@ -105,10 +106,11 @@ idle_print_status (gpointer user_data)
 }
 
 gboolean
-ostree_builtin_pull_local (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error)
+ostree_builtin_pull_local (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   gboolean ret = FALSE;
   GOptionContext *context;
+  gs_unref_object OstreeRepo *repo = NULL;
   const char *src_repo_path;
   int i;
   GHashTableIter hash_iter;
@@ -124,9 +126,8 @@ ostree_builtin_pull_local (int argc, char **argv, OstreeRepo *repo, GCancellable
   OtLocalCloneData *data = &datav;
 
   context = g_option_context_new ("SRC_REPO [REFS...] -  Copy data from SRC_REPO");
-  g_option_context_add_main_entries (context, options, NULL);
 
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error))
     goto out;
 
   data->dest_repo = g_object_ref (repo);
@@ -270,6 +271,7 @@ ostree_builtin_pull_local (int argc, char **argv, OstreeRepo *repo, GCancellable
     g_object_unref (data->dest_repo);
   if (context)
     g_option_context_free (context);
-  ostree_repo_abort_transaction (repo, cancellable, NULL);
+  if (repo)
+    ostree_repo_abort_transaction (repo, cancellable, NULL);
   return ret;
 }
index 46bf5c7e0c8a64b54b187373505f37ea3fedd389..ed013ca840fc752bfacbba33eb2d45690bd257ee 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "config.h"
 
+#include "ot-main.h"
 #include "ot-builtins.h"
 #include "ot-builtins-common.h"
 #include "ostree.h"
@@ -41,9 +42,10 @@ static int opt_depth = 0;
  };
 
 gboolean
-ostree_builtin_pull (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error)
+ostree_builtin_pull (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   GOptionContext *context;
+  gs_unref_object OstreeRepo *repo = NULL;
   gboolean ret = FALSE;
   gs_free char *remote = NULL;
   OstreeRepoPullFlags pullflags = 0;
@@ -52,9 +54,8 @@ ostree_builtin_pull (int argc, char **argv, OstreeRepo *repo, GCancellable *canc
   gs_unref_object OstreeAsyncProgress *progress = NULL;
 
   context = g_option_context_new ("REMOTE [BRANCH...] - Download data from remote repository");
-  g_option_context_add_main_entries (context, options, NULL);
 
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error))
     goto out;
 
   if (argc < 2)
index 9c291fbab580bf0785a441f80773c6fd891f88de..10dcc7215b9c0158e3d5cdebae2e092b5e890608 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "config.h"
 
+#include "ot-main.h"
 #include "ot-builtins.h"
 #include "ostree.h"
 #include "libgsystem.h"
@@ -34,19 +35,19 @@ static GOptionEntry options[] = {
 };
 
 gboolean
-ostree_builtin_refs (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error)
+ostree_builtin_refs (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   gboolean ret = FALSE;
   GOptionContext *context;
+  gs_unref_object OstreeRepo *repo = NULL;
   const char *refspec_prefix = NULL;
   gs_unref_hashtable GHashTable *refs = NULL;
   GHashTableIter hashiter;
   gpointer hashkey, hashvalue;
 
   context = g_option_context_new ("[PREFIX] - List refs");
-  g_option_context_add_main_entries (context, options, NULL);
 
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error))
     goto out;
 
   if (argc >= 2)
@@ -87,6 +88,7 @@ ostree_builtin_refs (int argc, char **argv, OstreeRepo *repo, GCancellable *canc
  out:
   if (context)
     g_option_context_free (context);
-  ostree_repo_abort_transaction (repo, cancellable, NULL);
+  if (repo)
+    ostree_repo_abort_transaction (repo, cancellable, NULL);
   return ret;
 }
index 6e63a4892f6b8c2ab7ee889a171ac1d86aa04e6a..541cf76fdba1654497594345205c4ce505c6c20f 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "config.h"
 
+#include "ot-main.h"
 #include "ot-builtins.h"
 #include "ostree.h"
 #include "otutil.h"
@@ -64,9 +65,10 @@ parse_keyvalue (const char  *keyvalue,
 }
 
 gboolean
-ostree_builtin_remote (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error)
+ostree_builtin_remote (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   GOptionContext *context;
+  gs_unref_object OstreeRepo *repo = NULL;
   gboolean ret = FALSE;
   const char *op;
   gs_free char *key = NULL;
@@ -75,9 +77,8 @@ ostree_builtin_remote (int argc, char **argv, OstreeRepo *repo, GCancellable *ca
   const char *remote_name;
 
   context = g_option_context_new ("OPERATION NAME [args] - Control remote repository configuration");
-  g_option_context_add_main_entries (context, options, NULL);
 
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error))
     goto out;
 
   if (argc < 3)
index a2ab429e8d506e977e9189b6aa75f8d960f42a69..0a72846dc7ec8c0cb0cbdf0aab68c847bf95e8c3 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "config.h"
 
+#include "ot-main.h"
 #include "ot-builtins.h"
 #include "ostree.h"
 #include "otutil.h"
@@ -83,11 +84,11 @@ out:
 gboolean
 ostree_builtin_reset (int           argc,
                       char        **argv,
-                      OstreeRepo   *repo,
                       GCancellable *cancellable,
                       GError      **error)
 {
   GOptionContext *context;
+  gs_unref_object OstreeRepo *repo = NULL;
   gboolean ret = FALSE;
   const char *ref;
   const char *target = NULL;
@@ -95,9 +96,8 @@ ostree_builtin_reset (int           argc,
   gs_free gchar *checksum = NULL;
 
   context = g_option_context_new ("[ARG] - Reset a ref to a previous commit");
-  g_option_context_add_main_entries (context, options, NULL);
 
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error))
     goto out;
 
   if (argc <= 2)
@@ -130,6 +130,7 @@ ostree_builtin_reset (int           argc,
  out:
   if (context)
     g_option_context_free (context);
-  ostree_repo_abort_transaction (repo, cancellable, NULL);
+  if (repo)
+    ostree_repo_abort_transaction (repo, cancellable, NULL);
   return ret;
 }
index 6c60b6fd4e5a0773899bf27e7d1a96e9e06a2286..f0835caecd473a53a159c641ec03f0cb83f38de5 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "config.h"
 
+#include "ot-main.h"
 #include "ot-builtins.h"
 #include "ostree.h"
 #include "otutil.h"
@@ -31,18 +32,18 @@ static GOptionEntry options[] = {
 };
 
 gboolean
-ostree_builtin_rev_parse (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error)
+ostree_builtin_rev_parse (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   GOptionContext *context;
+  gs_unref_object OstreeRepo *repo = NULL;
   gboolean ret = FALSE;
   const char *rev = "master";
   int i;
   gs_free char *resolved_rev = NULL;
 
   context = g_option_context_new ("REV - Output the target of a rev");
-  g_option_context_add_main_entries (context, options, NULL);
 
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error))
     goto out;
 
   if (argc < 2)
index 4b877828c68f1e44ba9a474052f90784b459c3f4..d09497450f003bef1aacf195b41eede5b8b2adbe 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "config.h"
 
+#include "ot-main.h"
 #include "ot-builtins.h"
 #include "ot-dump.h"
 #include "ostree.h"
@@ -199,17 +200,17 @@ print_if_found (OstreeRepo        *repo,
 }
 
 gboolean
-ostree_builtin_show (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error)
+ostree_builtin_show (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   GOptionContext *context;
+  gs_unref_object OstreeRepo *repo = NULL;
   gboolean ret = FALSE;
   const char *rev;
   gs_free char *resolved_rev = NULL;
 
   context = g_option_context_new ("OBJECT - Output a metadata object");
-  g_option_context_add_main_entries (context, options, NULL);
 
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error))
     goto out;
 
   if (argc <= 1)
index be535a62443114db99db366da111e84670f02c51..6fa01a1ba472a81cc574787c37c004a3c6647377 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "config.h"
 
+#include "ot-main.h"
 #include "ot-builtins.h"
 #include "ostree.h"
 #include "otutil.h"
@@ -36,16 +37,16 @@ static GOptionEntry options[] = {
 };
 
 gboolean
-ostree_builtin_static_delta (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error)
+ostree_builtin_static_delta (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   gboolean ret = FALSE;
   GOptionContext *context;
+  gs_unref_object OstreeRepo *repo = NULL;
   gs_unref_ptrarray GPtrArray *delta_names = NULL;
 
   context = g_option_context_new ("Manage static delta files");
-  g_option_context_add_main_entries (context, options, NULL);
 
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error))
     goto out;
 
   if (opt_apply)
index 2f9cae5be734837c306275d65f6320cc9c0f4d6e..d7bed4420f785689dc153d2a46236e109ab20c57 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "config.h"
 
+#include "ot-main.h"
 #include "ot-builtins.h"
 #include "ostree.h"
 #include "otutil.h"
@@ -32,15 +33,15 @@ static GOptionEntry options[] = {
 };
 
 gboolean
-ostree_builtin_summary (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error)
+ostree_builtin_summary (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   gboolean ret = FALSE;
   GOptionContext *context;
+  gs_unref_object OstreeRepo *repo = NULL;
 
   context = g_option_context_new ("Manage summary metadata");
-  g_option_context_add_main_entries (context, options, NULL);
 
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error))
     goto out;
 
   if (opt_update)
index 5ca1e4bf7774401db4eb6eba60f47abfeffff6a7..31c541a4fbb5f92cdd1af89d169700f100c2b530 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <libsoup/soup.h>
 
+#include "ot-main.h"
 #include "ot-builtins.h"
 #include "ostree.h"
 #include "otutil.h"
@@ -322,7 +323,7 @@ on_dir_changed (GFileMonitor  *mon,
 }
 
 gboolean
-ostree_builtin_trivial_httpd (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error)
+ostree_builtin_trivial_httpd (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   gboolean ret = FALSE;
   GOptionContext *context;
@@ -334,9 +335,7 @@ ostree_builtin_trivial_httpd (int argc, char **argv, OstreeRepo *repo, GCancella
 
   context = g_option_context_new ("[DIR] - Simple webserver");
 
-  g_option_context_add_main_entries (context, options, NULL);
-
-  if (!g_option_context_parse (context, &argc, &argv, error))
+  if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NO_REPO, NULL, cancellable, error))
     goto out;
 
   if (argc > 1)
index 5e3e4e64cc926732df23bf78e55f25e617f43868..9595ab4af0beb06b3e9ea937d7d54e2a05cce2c1 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "config.h"
 
+#include "ot-main.h"
 #include "ot-builtins-common.h"
 #include "otutil.h"
 
index b8b6507fc1a3535c5a0a974bc5753f9d60d63218..d423a3a0b5e8503a9001185e11af5961f5797659 100644 (file)
@@ -26,7 +26,7 @@
 
 G_BEGIN_DECLS
 
-#define BUILTINPROTO(name) gboolean ostree_builtin_ ## name (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error)
+#define BUILTINPROTO(name) gboolean ostree_builtin_ ## name (int argc, char **argv, GCancellable *cancellable, GError **error)
 
 BUILTINPROTO(admin);
 BUILTINPROTO(cat);
index 585e44f7f6cc7affb603d88a83d8067872aa1459..43e09a3ffb7220438e2386c7bb594c5c643eb0eb 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <gio/gio.h>
 
+#include <stdlib.h>
 #include <string.h>
 
 #include "ostree.h"
 #include "otutil.h"
 #include "libgsystem.h"
 
+static char *opt_repo;
+static char *opt_sysroot = "/";
+static gboolean opt_verbose;
+static gboolean opt_version;
+static gboolean opt_print_current_dir;
+
+static GOptionEntry global_entries[] = {
+  { "verbose", 'v', 0, G_OPTION_ARG_NONE, &opt_verbose, "Print debug information during command processing", NULL },
+  { "version", 0, 0, G_OPTION_ARG_NONE, &opt_version, "Print version information and exit", NULL },
+  { NULL }
+};
+
+static GOptionEntry repo_entry[] = {
+  { "repo", 0, 0, G_OPTION_ARG_STRING, &opt_repo, "Path to OSTree repository (defaults to /sysroot/ostree/repo)", "PATH" },
+  { NULL }
+};
+
+static GOptionEntry global_admin_entries[] = {
+  /* No description since it's hidden from --help output. */
+  { "print-current-dir", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_print_current_dir, NULL, NULL },
+  { "sysroot", 0, 0, G_OPTION_ARG_STRING, &opt_sysroot, "Create a new OSTree sysroot at PATH", "PATH" },
+  { NULL }
+};
+
+static GOptionContext *
+ostree_option_context_new_with_commands (OstreeCommand *commands)
+{
+  GOptionContext *context;
+  GString *summary;
+
+  context = g_option_context_new ("COMMAND");
+
+  summary = g_string_new ("Builtin Commands:");
+
+  while (commands->name != NULL)
+    {
+      g_string_append_printf (summary, "\n  %s", commands->name);
+      commands++;
+    }
+
+  g_option_context_set_summary (context, summary->str);
+
+  g_string_free (summary, TRUE);
+
+  return context;
+}
+
 int
-ostree_usage (char **argv,
-              OstreeCommand *commands,
+ostree_usage (OstreeCommand *commands,
               gboolean is_error)
 {
-  OstreeCommand *command = commands;
-  void (*print_func) (const gchar *format, ...);
+  GOptionContext *context;
+  gs_free char *help;
+
+  context = ostree_option_context_new_with_commands (commands);
+
+  g_option_context_add_main_entries (context, global_entries, NULL);
+
+  help = g_option_context_get_help (context, FALSE, NULL);
 
   if (is_error)
-    print_func = g_printerr;
+    g_printerr ("%s", help);
   else
-    print_func = g_print;
+    g_print ("%s", help);
 
-  print_func ("usage: %s --repo=PATH COMMAND [options]\n",
-              argv[0]);
-  print_func ("Builtin commands:\n");
+  g_option_context_free (context);
 
-  while (command->name)
-    {
-      print_func ("  %s\n", command->name);
-      command++;
-    }
   return (is_error ? 1 : 0);
 }
 
@@ -78,24 +124,16 @@ ostree_run (int    argc,
   OstreeCommand *command;
   GError *error = NULL;
   GCancellable *cancellable = NULL;
-  gs_unref_object OstreeRepo *repo = NULL;
-  const char *cmd = NULL;
-  const char *repo_arg = NULL;
-  gboolean want_help = FALSE;
-  gboolean skip;
+  const char *command_name = NULL;
+  gs_free char *prgname = NULL;
   gboolean success = FALSE;
-  int in, out, i;
+  int in, out;
 
   /* avoid gvfs (http://bugzilla.gnome.org/show_bug.cgi?id=526454) */
   g_setenv ("GIO_USE_VFS", "local", TRUE);
 
-  g_set_prgname (argv[0]);
-
   g_log_set_handler (NULL, G_LOG_LEVEL_MESSAGE, message_handler, NULL);
 
-  if (argc < 2)
-    return ostree_usage (argv, commands, TRUE);
-
   /*
    * Parse the global options. We rearrange the options as
    * necessary, in order to pass relevant options through
@@ -107,164 +145,217 @@ ostree_run (int    argc,
       /* The non-option is the command, take it out of the arguments */
       if (argv[in][0] != '-')
         {
-          skip = (cmd == NULL);
-          if (cmd == NULL)
-              cmd = argv[in];
-        }
-
-      /* The global long options */
-      else if (argv[in][1] == '-')
-        {
-          skip = FALSE;
-
-          if (g_str_equal (argv[in], "--"))
-            {
-              break;
-            }
-          else if (g_str_equal (argv[in], "--help"))
-            {
-              want_help = TRUE;
-            }
-          else if (g_str_equal (argv[in], "--repo") && in + 1 < argc)
+          if (command_name == NULL)
             {
-              repo_arg = argv[in + 1];
-              skip = TRUE;
-              in++;
-            }
-          else if (g_str_has_prefix (argv[in], "--repo="))
-            {
-              repo_arg = argv[in] + 7;
-              skip = TRUE;
-            }
-          else if (g_str_equal (argv[in], "--verbose"))
-            {
-              g_log_set_handler (NULL, G_LOG_LEVEL_DEBUG, message_handler, NULL);
-              skip = TRUE;
-            }
-          else if (cmd == NULL && g_str_equal (argv[in], "--version"))
-            {
-              g_print ("%s\n  %s\n", PACKAGE_STRING, OSTREE_FEATURES);
-              return 0;
-            }
-          else if (cmd == NULL)
-            {
-              g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                           "Unknown or invalid global option: %s", argv[in]);
-              goto out;
+              command_name = argv[in];
+              out--;
+              continue;
             }
         }
 
-      /* The global short options */
-      else
+      else if (g_str_equal (argv[in], "--"))
         {
-          skip = FALSE;
-          for (i = 1; argv[in][i] != '\0'; i++)
-            {
-              switch (argv[in][i])
-              {
-                case 'h':
-                  want_help = TRUE;
-                  break;
-                case 'v':
-                  g_log_set_handler (NULL, G_LOG_LEVEL_DEBUG, message_handler, NULL);
-                  skip = TRUE;
-                  break;
-                default:
-                  if (cmd == NULL)
-                    {
-                      g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                                   "Unknown or invalid global option: %s", argv[in]);
-                      goto out;
-                    }
-                  break;
-              }
-            }
+          break;
         }
 
-      /* Skipping this argument? */
-      if (skip)
-        out--;
-      else
-        argv[out] = argv[in];
+      argv[out] = argv[in];
     }
 
   argc = out;
 
-  if (cmd == NULL)
-    {
-      if (want_help)
-        {
-          success = TRUE;
-        }
-      else
-        {
-          g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                               "No command specified");
-        }
-      ostree_usage (argv, commands, !want_help);
-      goto out;
-    }
-
   command = commands;
   while (command->name)
     {
-      if (g_strcmp0 (cmd, command->name) == 0)
+      if (g_strcmp0 (command_name, command->name) == 0)
         break;
       command++;
     }
 
   if (!command->fn)
     {
-      gs_free char *msg = g_strdup_printf ("Unknown command '%s'", cmd);
-      g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, msg);
+      GOptionContext *context;
+      gs_free char *help;
+
+      context = ostree_option_context_new_with_commands (commands);
+
+      /* This will not return for some options (e.g. --version). */
+      if (ostree_option_context_parse (context, NULL, &argc, &argv, OSTREE_BUILTIN_FLAG_NO_REPO, NULL, cancellable, &error))
+        {
+          if (command_name == NULL)
+            {
+              g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                                   "No command specified");
+            }
+          else
+            {
+              g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                           "Unknown command '%s'", command_name);
+            }
+        }
+
+      help = g_option_context_get_help (context, FALSE, NULL);
+      g_printerr ("%s", help);
+
+      g_option_context_free (context);
+
       goto out;
     }
 
-  g_set_prgname (g_strdup_printf ("ostree %s", cmd));
+  prgname = g_strdup_printf ("%s %s", g_get_prgname (), command_name);
+  g_set_prgname (prgname);
 
-  if (repo_arg == NULL && !want_help &&
-      !(command->flags & OSTREE_BUILTIN_FLAG_NO_REPO))
+  
+  if (!command->fn (argc, argv, cancellable, &error))
+    goto out;
+
+  success = TRUE;
+ out:
+  g_assert (success || error);
+
+  if (error)
     {
-      GError *temp_error = NULL;
+      g_propagate_error (res_error, error);
+      return 1;
+    }
+  return 0;
+}
+
+gboolean
+ostree_option_context_parse (GOptionContext *context,
+                             const GOptionEntry *main_entries,
+                             int *argc,
+                             char ***argv,
+                             OstreeBuiltinFlags flags,
+                             OstreeRepo **out_repo,
+                             GCancellable *cancellable,
+                             GError **error)
+{
+  gs_unref_object OstreeRepo *repo = NULL;
+  gboolean success = FALSE;
+
+  /* Entries are listed in --help output in the order added.  We add the
+   * main entries ourselves so that we can add the --repo entry first. */
+
+  if (!(flags & OSTREE_BUILTIN_FLAG_NO_REPO))
+    g_option_context_add_main_entries (context, repo_entry, NULL);
+
+  if (main_entries != NULL)
+    g_option_context_add_main_entries (context, main_entries, NULL);
+
+  g_option_context_add_main_entries (context, global_entries, NULL);
+
+  if (!g_option_context_parse (context, argc, argv, error))
+    return FALSE;
+
+  if (opt_version)
+    {
+      g_print ("%s\n  %s\n", PACKAGE_STRING, OSTREE_FEATURES);
+      exit (EXIT_SUCCESS);
+    }
+
+  if (opt_verbose)
+    g_log_set_handler (NULL, G_LOG_LEVEL_DEBUG, message_handler, NULL);
+
+  if (opt_repo == NULL && !(flags & OSTREE_BUILTIN_FLAG_NO_REPO))
+    {
+      GError *local_error = NULL;
+
       repo = ostree_repo_new_default ();
-      if (!ostree_repo_open (repo, cancellable, &temp_error))
+      if (!ostree_repo_open (repo, cancellable, &local_error))
         {
-          if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+          if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
             {
-              g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
+              gs_free char *help = NULL;
+
+              g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                                    "Command requires a --repo argument");
-              g_error_free (temp_error);
-              ostree_usage (argv, commands, TRUE);
+              g_error_free (local_error);
+
+              help = g_option_context_get_help (context, FALSE, NULL);
+              g_printerr ("%s", help);
             }
           else
             {
-              g_propagate_error (&error, temp_error);
+              g_propagate_error (error, local_error);
             }
           goto out;
         }
     }
-  else if (repo_arg)
+  else if (opt_repo != NULL)
     {
-      gs_unref_object GFile *repo_file = g_file_new_for_path (repo_arg);
+      gs_unref_object GFile *repo_file = g_file_new_for_path (opt_repo);
+
       repo = ostree_repo_new (repo_file);
-      if (!(command->flags & OSTREE_BUILTIN_FLAG_NO_CHECK))
+      if (!(flags & OSTREE_BUILTIN_FLAG_NO_CHECK))
         {
-          if (!ostree_repo_open (repo, cancellable, &error))
+          if (!ostree_repo_open (repo, cancellable, error))
             goto out;
         }
     }
-  
-  if (!command->fn (argc, argv, repo, cancellable, &error))
-    goto out;
+
+  gs_transfer_out_value (out_repo, &repo);
 
   success = TRUE;
- out:
-  g_assert (success || error);
 
-  if (error)
+out:
+  return success;
+}
+
+gboolean
+ostree_admin_option_context_parse (GOptionContext *context,
+                                   const GOptionEntry *main_entries,
+                                   int *argc,
+                                   char ***argv,
+                                   OstreeSysroot **out_sysroot,
+                                   GCancellable *cancellable,
+                                   GError **error)
+{
+  gs_unref_object GFile *sysroot_path = NULL;
+  gs_unref_object OstreeSysroot *sysroot = NULL;
+  gboolean success = FALSE;
+
+  /* Entries are listed in --help output in the order added.  We add the
+   * main entries ourselves so that we can add the --sysroot entry first. */
+
+  g_option_context_add_main_entries (context, global_admin_entries, NULL);
+
+  if (!ostree_option_context_parse (context, main_entries, argc, argv, OSTREE_BUILTIN_FLAG_NO_REPO, NULL, cancellable, error))
+    goto out;
+
+  sysroot_path = g_file_new_for_path (opt_sysroot);
+  sysroot = ostree_sysroot_new (sysroot_path);
+
+  if (opt_print_current_dir)
     {
-      g_propagate_error (res_error, error);
-      return 1;
+      gs_unref_ptrarray GPtrArray *deployments = NULL;
+      OstreeDeployment *first_deployment;
+      gs_unref_object GFile *deployment_file = NULL;
+      gs_free char *deployment_path = NULL;
+
+      if (!ostree_sysroot_load (sysroot, cancellable, error))
+        goto out;
+
+      deployments = ostree_sysroot_get_deployments (sysroot);
+      if (deployments->len == 0)
+        {
+          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                       "Unable to find a deployment in sysroot");
+          goto out;
+        }
+      first_deployment = deployments->pdata[0];
+      deployment_file = ostree_sysroot_get_deployment_directory (sysroot, first_deployment);
+      deployment_path = g_file_get_path (deployment_file);
+
+      g_print ("%s\n", deployment_path);
+
+      exit (EXIT_SUCCESS);
     }
-  return 0;
+
+  gs_transfer_out_value (out_sysroot, &sysroot);
+
+  success = TRUE;
+
+out:
+  return success;
 }
+
index 49e310e863942f6d237690bb52f49c464dac4400..5f31b240728a26e8747ce01e35ead227bd22977f 100644 (file)
@@ -32,10 +32,22 @@ typedef enum {
 
 typedef struct {
   const char *name;
-  gboolean (*fn) (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error);
-  int flags; /* OstreeBuiltinFlags */
+  gboolean (*fn) (int argc, char **argv, GCancellable *cancellable, GError **error);
 } OstreeCommand;
 
 int ostree_run (int argc, char **argv, OstreeCommand *commands, GError **error);
 
-int ostree_usage (char **argv, OstreeCommand *commands, gboolean is_error);
+int ostree_usage (OstreeCommand *commands, gboolean is_error);
+
+gboolean ostree_option_context_parse (GOptionContext *context,
+                                      const GOptionEntry *main_entries,
+                                      int *argc, char ***argv,
+                                      OstreeBuiltinFlags flags,
+                                      OstreeRepo **out_repo,
+                                      GCancellable *cancellable, GError **error);
+
+gboolean ostree_admin_option_context_parse (GOptionContext *context,
+                                            const GOptionEntry *main_entries,
+                                            int *argc, char ***argv,
+                                            OstreeSysroot **out_sysroot,
+                                            GCancellable *cancellable, GError **error);